<?php
class cmspad_logger_file implements ILogger{
	
	private $filepath;
	
	private $filename;
	
	private $filesize;
	
	private $fileloop;
	
	private $loglevel;
	
	private $logpattern;
	
	private $logdformat;
	
	private $logtformat;
	
	private $messages;
	
	private $msglength;
	
	public function __construct(){
		global $_CONFIG;
		if(isset($_CONFIG['LOGGING']['PATH']) && cmspad_create_directory($_CONFIG['LOGGING']['PATH'])){
			$this->filepath = str_replace('\\','/',$_CONFIG['LOGGING']['PATH']);
			if(substr($this->filepath,-1) != '/'){
				$this->filepath .= '/';
			}
		}else{
			$this->filepath = CMSPAD_ABSPATH . 'log/';
			cmspad_create_directory($this->filepath);
		}
		
		if(isset($_CONFIG['LOGGING']['FILE'])){
			$this->filename = $_CONFIG['LOGGING']['FILE'];
		}else{
			$this->filename = 'cmspad.log';
		}
		
		if(isset($_CONFIG['LOGGING']['SIZE'])){
			$this->filesize = intval($_CONFIG['LOGGING']['SIZE']);
		}else{
			$this->filesize = false;
		}
		
		if(isset($_CONFIG['LOGGING']['LOOP'])){
			switch($_CONFIG['LOGGING']['LOOP']){
				case 'hour':
				case 'day':
				case 'month':
				case 'year':
				case 'size':
				case 'h':
				case 'd':
				case 'm':
				case 'y':
				case 's':
					$this->fileloop = $_CONFIG['LOGGING']['LOOP'];
					break;
				default:
					trigger_error('Invalid logger loop mode(' . $_CONFIG['LOGGING']['LOOP'] . '), needs: hour, day, month, year, size',E_USER_WARNING);
					$this->fileloop = false;
					break;
			}
		}else{
			$this->fileloop = false;
		}
		
		if(isset($_CONFIG['LOGGING']['LEVEL'])){
			switch(intval($_CONFIG['LOGGING']['LEVEL'])){
				case E_ERROR:
				case E_PARSE:
				case E_CORE_ERROR:
				case E_COMPILE_ERROR:
				case E_USER_ERROR:
					$this->loglevel = Logging::$ERROR;
					break;
				case E_WARNING:
				case E_CORE_WARNING:
				case E_COMPILE_WARNING:
				case E_USER_WARNING:
					$this->loglevel = Logging::$WARN;
					break;
				case E_NOTICE:
				case E_USER_NOTICE:
				case E_STRICT:
					$this->loglevel = Logging::$NOTICE;
					break;
				case E_RECOVERABLE_ERROR:
					$this->loglevel = Logging::$FATAL;
					break;
				default:
					$this->loglevel = Logging::$DEBUG;
					break;
			}
		}else{
			$this->loglevel = Logging::$DEBUG;
		}
		
		if(isset($_CONFIG['LOGGING']['PATTERN'])){
			$this->logpattern = $_CONFIG['LOGGING']['PATTERN'];
		}else{
			$this->logpattern = '%d %t [%p][%f:%l] %m';
		}
		
		if(isset($_CONFIG['LOGGING']['DATE_FORMAT'])){
			$this->logdformat = $_CONFIG['LOGGING']['DATE_FORMAT'];
		}else{
			$this->logdformat = 'Y-m-d';
		}
		
		if(isset($_CONFIG['LOGGING']['TIME_FORMAT'])){
			$this->logtformat = $_CONFIG['LOGGING']['TIME_FORMAT'];
		}else{
			$this->logtformat = 'H:i:s';
		}
		
		$this->messages = array();
		$this->msglength = 0;
	}
	
	public function __destruct(){
		if(!empty($this->messages)){
			if($this->fileloop){
				switch($this->fileloop){
					case 'hour':
					case 'h':
						$loop = date('H');
						break;
					case 'day':
					case 'd':
						$loop = date('d');
						break;
					case 'month':
					case 'm':
						$loop = date('m');
						break;
					case 'year':
					case 'y':
						$loop = date('Y');
						break;
					default:
						for($i = 1;file_exists($file = $this->filepath . str_replace('%t',$i,$this->filename));$i++){
							if(filesize($file) + $this->msglength <= $this->filesize){
								$loop = $i;
								break;
							}
						}
						if(!isset($loop)){
							$loop = $i;
						}
						break;
				}
				
				$file = $this->filepath . str_replace('%t',$loop,$this->filename);
			}else{
				$file = $this->filepath . $this->filename;
			}
			
			$fp = fopen($file,'a');
			foreach($this->messages as $message){
				fwrite($fp,$message . "\r\n");
			}
			fflush($fp);
			fclose($fp);
		}
	}
	
	/**
	 * @see Logger::log()
	 *
	 * @param integer $level
	 * @param string $messages
	 * @param string $file
	 * @param integer $line
	 */
	public function log($level,$messages,$file,$line){
		if($level < $this->loglevel){
			return;
		}
		
		if(!is_array($messages)){
			$messages = array($messages);
		}
		
		switch($level){
			case Logging::$DEBUG:
				$l = 'DEBUG';
				break;
			case Logging::$INFO:
				$l = 'INFO';
				break;
			case Logging::$NOTICE:
				$l = 'NOTICE';
				break;
			case Logging::$WARN:
				$l = 'WARN';
				break;
			case Logging::$ERROR:
				$l = 'ERROR';
				break;
			case Logging::$FATAL:
				$l = 'FATAL';
				break;
			default:
				$l = 'CUSTOM';
				break;
		}
		
		$remoteAddr = $_SERVER['REMOTE_ADDR'];
		foreach($messages as $message){
			$msg = str_replace('%d',date($this->logdformat),$this->logpattern);
			$msg = str_replace('%t',date($this->logtformat),$msg);
			$msg = str_replace('%p',$l,$msg);
			$msg = str_replace('%m',$message,$msg);
			$msg = str_replace('%f',$file,$msg);
			$msg = str_replace('%l',$line,$msg);
			$msg = str_replace('%a',$remoteAddr,$msg);
			$this->messages[] = $msg;
			// plus 2 bytes for "\r\n"
			$this->msglength += strlen($msg) + 2;
		}
	}
}
?>